<?php
namespace app\data\util;

/**
 * CSV文件的生成、读取、下载
 * @author Gavin
 * @since 2018-08-09
 */
class CsvHelper
{
    public static $message = array();

    /**
     * 1.生成 csv 文件
     * @param array $rows [二维数组数据]
     * @param array $header [一维数组名称]
     * @param array $mode [文件写入模式]
     * @param boolean $filename
     */
    public static function createCSV($rows, $header = array(), $filename = NULL, $mode = 'w')
    {
        setlocale(LC_ALL, 'zh_CN');
        if (empty($filename)) $filename = date('YmdHis') . mt_rand(10000, 99999) . '.csv';
        if (pathinfo($filename, PATHINFO_EXTENSION) !== 'csv') $filename .= '.csv';

        if (strpos(PHP_OS, "Linux") !== false) {
            touch($filename);  //这个中文不乱码
        } else {
            $filename = iconv('UTF-8', 'GBK//IGNORE', $filename);
        }


        $dirname = dirname($filename);
        if (!is_dir($dirname)) {
            @mkdir($dirname, 0777, true);
        }
        if (($fp = fopen($filename, $mode)) !== false) {
            if (!empty($header)) fputcsv($fp, self::utf8ToGbk($header));
            foreach ($rows as $row) {
                fputcsv($fp, self::utf8ToGbk($row));
            }
            fclose($fp);
            if (strpos(PHP_OS, "Linux") === false) {
                $filename = iconv('GBK', 'UTF-8//IGNORE', $filename);
            }

            $result = array('status' => 200, 'data' => $filename);
        } else {
            $result = array('status' => 500, 'data' => '打开文件失败');
        }
        return $result;
    }

    public static function ArrayConvUtf8($arr)
    {
        if (!is_array($arr)) $arr = array($arr);
        foreach ($arr as $k => $v) {
            $v = self::removeBrLabel($v);
            $arr[$k] = self::stringConvUtf8($v);
        }
        return $arr;
    }

    private static function utf8ToGbk($arr)
    {
        if (!is_array($arr)) $arr = array($arr);
        foreach ($arr as $k => $v) {
            $v = self::removeBrLabel($v);
            $arr[$k] = iconv('UTF-8', 'GBK//IGNORE', $v);   //描述为空
        }
        return $arr;
    }

    public static function stringConvUtf8($param)
    {
        $code = mb_detect_encoding($param);
        if ($code !== false && $code != 'UTF-8') {
            $param = iconv($code, 'UTF-8', $param);
        }
        return $param;
    }

    public static function removeBrLabel($string)
    {
        if (strpos($string, '</br>') !== false) {
            $string = preg_replace('#</br>#i', ' ', $string);
        }
        return $string;
    }

    /**
     * 2.读取 csv 文件
     * @return [array]
     */
    public static function readCSV($filename)
    {
        setlocale(LC_ALL, 'zh_CN');
        $filename = './' . iconv('UTF-8', 'GBK//IGNORE', $filename);
        $dataList = array();
        if (($handle = fopen($filename, 'r')) !== false) {
            while (($row = fgetcsv($handle, 0, ',')) !== false) {
                $dataList[] = $row;
            }
        }
        return $dataList;
    }


    /**
     * 3.直接输出 csv 文件
     * @param array $rows [二维数组数据]
     * @param array $header [一维数组名称]
     * @param boolean $filename
     */
    public static function exportCSV($rows, $header = array(), $filename = false)
    {
        #浏览器
        setlocale(LC_ALL, 'zh_CN');
        if (PHP_SAPI == 'cli') trigger_error('Must be run from a Web Browser', E_USER_ERROR);

        if (empty($filename)) $filename = date('YmdHis') . mt_rand(10000, 99999) . '.csv';
        if (pathinfo($filename, PATHINFO_EXTENSION) !== 'csv') $filename .= '.csv';
        ob_end_clean();
        header("Content-type:application/csv");
        header('Content-Type: text/csv; charset=utf-8');
        header("Cache-Control:must-revalidate,post-check=0,pre-check=0");
        header('Content-Disposition: attachment; filename=' . str_replace(' ', '', $filename));
        header('Content-Transfer-Encoding: binary');
        header('Expires: 0');
        header('Cache-Control: must-revalidate');
        header('Pragma: public');
        $output = fopen('php://output', 'w');

        if (!empty($header)) fputcsv($output, self::ArrayConvUtf8($header));
        foreach ($rows as $row) {
            fputcsv($output, self::ArrayConvUtf8($row));
        }
        flush();
        fclose($output);
        // exit();
    }

    /**
     *  * 4.把多个 csv 文件合并成一个文件
     * @param array $pathArr 文件路径数组
     * @param string $filename 文件名
     * @return array|bool
     */
    public static function mergeCSV($pathArr, $filename)
    {
        setlocale(LC_ALL, 'zh_CN');
        $folder = UPLOAD_FILE_DOMAIN_NAME."/excel/".date('Ym/d/');
        $path = FCPATH .$folder;
        if(!is_dir($path)) mkdir($path, 0777, true);
        $fileAddress = $path.$filename.'.csv';

        if ( strpos(PHP_OS,"Linux")!==false){
            touch($fileAddress);  //这个中文不乱码
        }else{
            $fileAddress = iconv('utf-8','gb2312//IGNORE',$fileAddress);
            $filename = iconv('utf-8','gb2312//IGNORE',$filename);

        }


        #写入要保存的文件
        if(($save = fopen($fileAddress, 'a+')) === false){
            return false;
        }
        foreach ($pathArr as $value){

            $path_name = FCPATH . $value;
            #文件
            if(is_file($path_name))
            {
                $fp = fopen($path_name, 'r');
                if($csv_str = fread($fp, filesize($path_name))){
                    fwrite($save, $csv_str);
                    fclose($fp);
                }
                //合并完删除子文件
                unlink($path_name);
            }
        }
        fclose($save);


        if ( strpos(PHP_OS,"Linux")===false){
            $filename =  iconv('GBK', 'UTF-8//IGNORE', $filename);
        }

        return $folder.$filename.'.csv';
    }

    /**
     * 5.按年月日，创建 csv 文件保存目录
     * @param string $app_root [项目目录]
     * @param string $log_path [日志下载目录]
     */
    public static function csvSavePath($app_root = '.', $log_path = 'upload/csv_download/')
    {
        $path = $app_root . '/' . $log_path . date('Ym/d/');
        if (!is_dir($path)) {
            mkdir($path, 0777, true);
        }
        return $path;
    }

    /**
     * 6.直接下载的数据
     */
    public static function downloadCsvFile($filename, $newname = '')
    {
        if (!file_exists($filename)) die('文件未找到【' . $filename . '】');
        if (empty($newname)) $newname = basename($filename);
        $ext = pathinfo($filename, PATHINFO_EXTENSION);
        if (in_array($ext, ['xls', 'xlsx'])) {
            $newname .= '.' . $ext;
        }
        if (!in_array(pathinfo($newname, PATHINFO_EXTENSION), ['csv', 'xls', 'xlsx'])) $newname .= '.csv';

        header('Content-Description: File Transfer');
        header('Content-Type: text/csv; charset=utf-8');
        header('Content-Disposition: attachment; filename=' . str_replace(' ', '', $newname));
        header('Content-Transfer-Encoding: binary');
        header('Expires: 0');
        header('Cache-Control: must-revalidate');
        header('Pragma: public');
        header('Content-Length: ' . filesize($filename));

        ob_clean();
        flush();
        readfile($filename);
        unlink($filename);
        exit;
    }
}